﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq.Expressions;
using Loki.Utils;

namespace Loki.UI.Win
{
    public class NotifyPropertyChangedWrapper<T> : INotifyPropertyChanged
    {
        private static Dictionary<string, PropertyChangedEventArgs> _EventArgs = new Dictionary<string, PropertyChangedEventArgs>();
        private static object _lock = new object();

        private string _PropertyName;
        public NotifyPropertyChangedWrapper(Expression<Func<T, object>> P_Property)
        {
            _PropertyName = ExpressionHelper.GetProperty(P_Property).Name;
            lock (_lock)
            {
                if (!_EventArgs.ContainsKey(_PropertyName))
                {
                    _EventArgs[_PropertyName] = ObservableHelper.CreateChangedArgs(P_Property);
                }
            }
        }

        #region Event
        private readonly object PropertyChangedEventLock = new object();
        private PropertyChangedEventHandler PropertyChangedEvent;

        /// <summary>
        /// Event raised after the <see cref="Text" /> property value has changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged
        {
            add
            {
                lock (PropertyChangedEventLock)
                {
                    PropertyChangedEvent += value;
                }
            }
            remove
            {
                lock (PropertyChangedEventLock)
                {
                    PropertyChangedEvent -= value;
                }
            }
        }

        /// <summary>
        /// Raises the <see cref="PropertyChanged" /> event.
        /// </summary>
        /// <param name="e"><see cref="PropertyChangedEventArgs" /> object that provides the arguments for the event.</param>
        protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            PropertyChangedEventHandler handler = null;

            lock (PropertyChangedEventLock)
            {
                handler = PropertyChangedEvent;

                if (handler == null)
                    return;
            }

            handler(this, e);
        }
        #endregion

        public void EventBridge(object sender, EventArgs e)
        {
            OnPropertyChanged(_EventArgs[_PropertyName]);
        }
    }
}
